package com.lcc.dingtalk.robot.controller;

import com.lcc.dingtalk.robot.pojo.message.req.DingDingReq;
import com.lcc.dingtalk.robot.pojo.message.resp.DingTalkBaseResp;
import com.lcc.dingtalk.robot.pojo.message.resp.DingTalkTextResp;
import com.lcc.dingtalk.robot.service.message.MessageService;
import com.lcc.dingtalk.robot.util.SignUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;


/**
 * @author lincc
 * @version 1.0 2020/7/27
 */
@Api(tags = "消息相关接口")
@RestController
@RequestMapping("/message")
@Slf4j
public class MessageController {

    @Value("${dingtalk.robot.appSecret}")
    private String appSecret;

    @Autowired
    private MessageService messageService;

    private Map<String, String> getHeadersInfo(HttpServletRequest request) {
        Map<String, String> map = new HashMap<>(5);
        Enumeration headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String key = (String) headerNames.nextElement();
            String value = request.getHeader(key);
            map.put(key, value);
        }
        return map;
    }

    @ApiOperation(value = "消息响应接口")
    @PostMapping("answer.do")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "timestamp", value = "1577262236757", required = true),
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "sign", value = "签名值", required = true),
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "Content-Type", value = "application/json; charset=utf-8", required = true)})
    public DingTalkBaseResp answer(@RequestBody DingDingReq req, HttpServletRequest request) throws Exception {
        Map<String, String> headersInfo = this.getHeadersInfo(request);
        log.info("请求头信息[{}]", headersInfo);
        String timestamp = headersInfo.get("timestamp");
        long s = (System.currentTimeMillis() - Long.parseLong(timestamp)) / (1000 * 60 * 60);
        if (Math.abs(s) > 1) {
            return DingTalkTextResp.context("时间戳超过一小时，非法请求");
        }
        String sign = SignUtil.hmac(timestamp, appSecret);
        if (!headersInfo.get("sign").equals(sign)) {
            log.info("签名验证不通过,签名字符串[{}],待校验签名[{}]", sign, headersInfo.get("sign"));
            return DingTalkTextResp.context("签名验证不通过，非法请求");
        }
        String content = req.getText().getContent().trim();
        log.info("请求关键字[{}]", content);
        String info = messageService.autoAnswer(content).replaceAll("\\\\n", "\n")
                .replaceAll("\\\\t", "\t");
        log.info("响应文本[{}]", info);
        return DingTalkTextResp.context(info);
    }
}
